using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ZedGraph;

namespace FTFSmartCar
{
    public partial class WaveViewer : Form
    {


        #region visualization variables
        PointPairList[] PhaselistP = new PointPairList[3];
        PointPairList[] PhaselistM = new PointPairList[3];
        GraphPane[] MyPane = new GraphPane[3];
        MasterPane MyMasterPane;
        #endregion

        public WaveViewer()
        {
            InitializeComponent();
            InitWaveViewer();
        }

        double [] PulseOnTime = new double[3];
        double Frequency = 0;
        double[] Phase = new double[2];

        public void SetWaveViewerParameters(double PulseOnTimeCh1, double PulseOnTimeCh2, double PulseOnTimeCh3,
                                     double eFrequency, double Phase2, double Phase3)
        {
            PulseOnTime[0] = PulseOnTimeCh1;
            PulseOnTime[1] = PulseOnTimeCh2;
            PulseOnTime[2] = PulseOnTimeCh3;
            Phase[0] = Phase2;
            Phase[1] = Phase3;
            Frequency = eFrequency;
            UpdateWaveViewer();
        }


        void InitWaveViewer()
        {
            for (int i = 0; i < 3; i++)
            {
                MyPane[i] = new GraphPane();
                MyPane[i].Title.Text = "Ideal Output  - Phase " + (i + 1);
                MyPane[i].XAxis.Title.Text = "Time (Seconds)";
                MyPane[i].YAxis.Title.Text = "Relative Amplitude";
                MyPane[i].YAxis.Scale.MaxAuto = false;
                MyPane[i].YAxis.Scale.MinAuto = false;
                MyPane[i].YAxis.Scale.Min = 0;
                MyPane[i].YAxis.Scale.MinAuto = false;
                MyPane[i].YAxis.Scale.Max = 110;
                MyPane[i].YAxis.MajorGrid.IsVisible = true;

                MyPane[i].XAxis.Scale.MaxAuto = false;
                MyPane[i].XAxis.Scale.MinAuto = false;
                MyPane[i].XAxis.Scale.Min = 0;
                MyPane[i].XAxis.Scale.MinAuto = false;
                MyPane[i].XAxis.Scale.Max = 1 / (Frequency);

                MyPane[i].XAxis.Scale.MaxGrace = 0.2;
                MyPane[i].XAxis.Scale.MinGrace = 0.2;

                MyPane[i].XAxis.MajorGrid.IsVisible = true;
            }

            MyMasterPane = IdealOutput.MasterPane;

            MyMasterPane.PaneList.Clear();
            MyMasterPane.Title.Text = "test";
            for (int i = 0; i < 3; i++)
            {
                MyMasterPane.Add(MyPane[i]);
            }

            IdealOutput.AxisChange();

            using (Graphics g = this.CreateGraphics())
            {
                MyMasterPane.SetLayout(g, PaneLayout.SingleColumn);
            }

            for (int i = 0; i < 3; i++)
            {
                PhaselistM[i] = new PointPairList();
                PhaselistP[i] = new PointPairList();
            }

        }

        private void UpdateWaveViewer()
        {
            const double NumPointsToPlot = 200;
            const double NumCycles = 2;
            // Make up some data arrays based on the Sine function
            double t = 0;

            double[] Phase_P = new double[3];
            double[] Phase_M = new double[3];

            double Period = 1.0 / (double)Frequency;

            for (int j = 0; j < 3; j++)
            {
                PhaselistM[j].Clear();
                PhaselistP[j].Clear();
            }

            for (int j = 0; j < 3; j++)
            {
                for (int i = 0; i < NumPointsToPlot; i++)
                {
                    t = (i / NumPointsToPlot) * Period;

                        double phi_M, phi_P, phi_Lim, A_M, A_P;

                        switch (j)
                        {
                            default:
                            case 0:
                                phi_P = NumCycles * 2 * Math.PI * ((double)i / NumPointsToPlot);
                                phi_M = phi_P - Math.PI;
                                phi_Lim = (PulseOnTime[0]* Math.PI / 100);
                                break;
                            case 1:
                                phi_P = NumCycles * 2 * Math.PI * ((double)i / NumPointsToPlot) - (Phase[0]* Math.PI / 180.0);
                                phi_M = phi_P - Math.PI;
                                phi_Lim = (PulseOnTime[1] * Math.PI / 100);
                                break;
                            case 2:
                                phi_P = NumCycles * 2 * Math.PI * ((double)i / NumPointsToPlot) - (Phase[1] * Math.PI / 180.0);
                                phi_M = phi_P - Math.PI;
                                phi_Lim = (PulseOnTime[2] * Math.PI / 100);
                                break;
                        }

                        A_M = Math.Sin(phi_M);
                        A_P = Math.Sin(phi_P);
                        
                        if (A_P > 0)
                        {

                            if ((phi_P < phi_Lim) && (phi_P > 0))
                            {
                                Phase_P[j] = 100;
                            }
                            else
                            {
                                Phase_P[j] = 0;
                            }
                        }
                        else
                        {
                            Phase_P[j] = 0;
                        }

                        if (A_M > 0)
                        {
                            if ((phi_M < phi_Lim) && (phi_M > 0))
                            {
                                Phase_M[j] = 100;
                            }
                            else
                            {
                                Phase_M[j] = 0;
                            }
                        }
                        else
                        {
                            Phase_M[j] = 0;
                        }
                       
                        PhaselistP[j].Add(t, Phase_P[j]);
                        PhaselistM[j].Add(t, Phase_M[j]);
                    }
                
            }
            MyPane[0].CurveList.Clear();
            MyPane[1].CurveList.Clear();
            MyPane[2].CurveList.Clear();

            LineItem[] MyCurve = new LineItem[6];

            MyCurve[0] = MyPane[0].AddCurve("Phase 1-P", PhaselistP[0], Color.Red, SymbolType.None);
            MyCurve[1] = MyPane[0].AddCurve("Phase 1-M", PhaselistM[0], Color.DarkRed, SymbolType.None);
            MyCurve[2] = MyPane[1].AddCurve("Phase 2-P", PhaselistP[1], Color.Green, SymbolType.None);
            MyCurve[3] = MyPane[1].AddCurve("Phase 2-M", PhaselistM[1], Color.DarkGreen, SymbolType.None);
            MyCurve[4] = MyPane[2].AddCurve("Phase 3-P", PhaselistP[2], Color.Blue, SymbolType.None);
            MyCurve[5] = MyPane[2].AddCurve("Phase 3-M", PhaselistM[2], Color.DarkBlue, SymbolType.None);

            MyPane[0].XAxis.Scale.Max = Period;
            MyPane[0].XAxis.Scale.Min = 0;
            MyPane[1].XAxis.Scale.Max = Period;
            MyPane[1].XAxis.Scale.Min = 0;
            MyPane[2].XAxis.Scale.Max = Period;
            MyPane[2].XAxis.Scale.Min = 0;

            IdealOutput.AxisChange();
            IdealOutput.Invalidate();

        }

        #region GUI Callbacks

        private void WaveViewer_Resize(object sender, EventArgs e)
        {
            IdealOutput.Location = new Point(10, 10);
            // Leave a small margin around the outside of the control
            IdealOutput.Size = new Size(ClientRectangle.Width - 20,
                                    ClientRectangle.Height - 20);
            
            UpdateWaveViewer();
        }

        private void WaveViewer_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = true;
            this.Hide();
        }
        #endregion


    }
}